package cn.tedu.oa.sys.service.realm;

import cn.tedu.oa.sys.dao.MenuDao;
import cn.tedu.oa.sys.dao.RoleMenuDao;
import cn.tedu.oa.sys.dao.UserRoleDao;
import cn.tedu.oa.sys.entity.User;
import cn.tedu.oa.sys.service.UserService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class ShiroUserRealm extends AuthorizingRealm {
    @Autowired
    private UserService userService;
    @Autowired
    private UserRoleDao userRoleDao;
    @Autowired
    private RoleMenuDao roleMenuDao;
    @Autowired
    private MenuDao menuDao;
    //授权方法
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principal) {
        //获取用户id
        //返回值对应认证信息时的封装
        User user=(User)principal.getPrimaryPrincipal();
        Integer userId = user.getId();
        //1.基于用户id获取权限信息(菜单权限标识)(用户《--》角色《--》菜单)
        //获取用户对应角色信息
        List<Integer> roleIds = null;
        if(userId!=null){
            roleIds=userRoleDao.getRoleIdsByUserId(userId);
        }
        //获取角色对应能操作的菜单信息
        List<Integer> menuIds = null;
        if(!roleIds.isEmpty()){
            menuIds=roleMenuDao.getMenuIdsByRoleIds(roleIds.toArray(new  Integer[]{}));
        }
        //获取菜单对应权限信息
        List<String> permissions = null;
        if(menuIds!=null&&!menuIds.isEmpty()){
            permissions=menuDao.getPermissionsByIds(menuIds.toArray(new Integer[]{}));
        }
        //2.封装权限信息
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        Set<String> perSet = new HashSet<String>();
        if(permissions!=null&&!permissions.isEmpty()){
            for(String per:permissions){
                if(per!=null&&!per.isEmpty()){
                    perSet.add(per);
                }
            }
        }
        info.setStringPermissions(perSet);
        //返回封装信息
        return info;
    }

    //认证方法
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        //1.从token对象获取用户名(用户输入的)
        UsernamePasswordToken upToken = (UsernamePasswordToken) token;
        String username = upToken.getUsername();
        //2.基于用户名查询用户信息并进行身份校验
        User user = userService.getUserByUsername(username);
        if (user == null) {
            throw new AuthenticationException("此用户不存在");
        }
        if (user.getValid() == 1) {
            throw new AuthenticationException("此用户已被禁用");
        }
        //3.对用户信息进行封装
        ByteSource credentialsSalt = ByteSource.Util.bytes(user.getSalt());
        //principal 用户身份
        //hashedCredentials已加密的凭证
        //credentialsSalt 密码加密时使用的盐
        //realmName 当前方法所在对象的名字
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getPassword(), credentialsSalt, getName());
        return info;
    }

}
